﻿using System;
using System.Collections.Generic;
using System.Text;

namespace BigNumber
{
  public interface IBigNumber
  {
    /// <summary>
    /// Returns true if number < 0
    /// </summary>
    bool IsNegative { get; }

    /// <summary>
    /// Returns true if the number is 0
    /// </summary>
    bool IsZero { get; }

    /// <summary>
    /// Returns true if the number is 1 or -1
    /// </summary>
    bool IsOne { get; }

    /// <summary>
    /// Initializes the number from a valid string
    /// </summary>
    /// <param name="number">A string representing a number</param>
    void Initialize(string number);

    /// <summary>
    /// Multiplies the number by -1 without creating a new instance of the number
    /// </summary>
    void Negate();

    #region Functions to allow the usage of number in generics
    IBigNumber IAdd(IBigNumber second);

    IBigNumber ISub(IBigNumber second);

    IBigNumber IMul(IBigNumber second);

    IBigNumber IDiv(IBigNumber second);

    IBigNumber IMod(IBigNumber second);

    IBigNumber IClone();

    IBigNumber IConstruct(string number);
    
    void IAbs();

    bool IEqual(IBigNumber second);

    bool ISmaller(IBigNumber second);


    #endregion
  }

  public class BigNumberEqualityComparer<T> : IEqualityComparer<T>
  where T : IBigNumber
  {

    #region IEqualityComparer<T> Members

    public bool Equals(T x, T y)
    {
      if (x == null && y == null) return true;
      if (x == null || y == null) return false;
      return x.IEqual(y);
    }

    public int GetHashCode(T obj)
    {
      return obj.ToString().GetHashCode();
    }

    #endregion
  }


  public interface IIntegerBigNumber  : IBigNumber { }
  public interface IRationalBigNumber : IBigNumber { }

}
